package com.vegetable.modules.service.stock.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.common.utils.PageUtils;
import com.vegetable.modules.entity.baseData.Products;
import com.vegetable.modules.entity.baseData.ProductSpec;
import com.vegetable.modules.entity.stock.Stock;
import com.vegetable.modules.entity.stock.StockAlert;
import com.vegetable.modules.entity.stock.StockAlertRecord;
import com.vegetable.modules.entity.stock.po.StockAlertQueryPO;
import com.vegetable.modules.entity.stock.po.StockAlertSavePO;
import com.vegetable.modules.mapper.stock.StockAlertMapper;
import com.vegetable.modules.service.baseData.IProductSpecService;
import com.vegetable.modules.service.baseData.IProductsService;
import com.vegetable.modules.service.stock.IStockAlertRecordService;
import com.vegetable.modules.service.stock.IStockAlertService;
import com.vegetable.modules.service.stock.IStockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 库存预警设置表 服务实现类
 * </p>
 *
 * @author wangruijie
 * @since 2024-09-09
 */
@Slf4j
@Service
public class StockAlertServiceImpl extends ServiceImpl<StockAlertMapper, StockAlert> implements IStockAlertService {

    @Resource
    private StockAlertMapper stockAlertMapper;
    
    @Lazy
    @Resource
    private IStockService stockService;
    
    @Resource
    private IStockAlertRecordService stockAlertRecordService;
    
    @Resource
    private IProductsService productsService;
    
    @Resource
    private IProductSpecService productSpecService;

    @Override
    public PageUtils queryPage(StockAlertQueryPO po) {
        Page<StockAlert> page = new Page<>(po.getPage(), po.getSize());
        IPage<StockAlert> result = stockAlertMapper.selectAlertPage(page, po);
        return new PageUtils(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdateAlert(StockAlertSavePO po, Long userId) {
        log.info("保存库存预警设置，商品ID：{}，规格ID：{}，预警数量：{}", po.getCommodityId(), po.getSpecsId(), po.getAlertQuantity());
        
        // 查询商品信息
        Products product = productsService.getById(po.getCommodityId());
        if (ObjectUtil.isNull(product)) {
            throw new RuntimeException("商品不存在");
        }
        
        // 查询规格信息（如果有规格ID）
        ProductSpec productSpec = null;
        if (ObjectUtil.isNotNull(po.getSpecsId())) {
            productSpec = productSpecService.getById(po.getSpecsId());
            if (ObjectUtil.isNull(productSpec)) {
                throw new RuntimeException("商品规格不存在");
            }
        }
        
        // 检查是否已存在相同的预警设置
        StockAlert existAlert = stockAlertMapper.selectByCommodityAndSpecs(po.getCommodityId(), po.getSpecsId());
        
        StockAlert stockAlert;
        if (ObjectUtil.isNotNull(existAlert)) {
            // 更新现有预警设置
            stockAlert = existAlert;
            BeanUtils.copyProperties(po, stockAlert);
            stockAlert.setUpdateTime(new Date());
        } else {
            // 创建新的预警设置
            stockAlert = new StockAlert();
            BeanUtils.copyProperties(po, stockAlert);
            stockAlert.setCommodityName(product.getCommonName());
            stockAlert.setCommonCode(product.getCommonCode());
            if (ObjectUtil.isNotNull(productSpec)) {
                stockAlert.setSpecsName(productSpec.getName());
            }
            stockAlert.setCreateUserId(userId);
            stockAlert.setCreateTime(new Date());
        }
        
        return saveOrUpdate(stockAlert);
    }

    @Override
    public StockAlert getAlertByCommodityAndSpecs(Long commodityId, Long specsId) {
        return stockAlertMapper.selectByCommodityAndSpecs(commodityId, specsId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateEnabled(List<Long> ids, Integer isEnabled) {
        if (CollectionUtil.isEmpty(ids)) {
            return false;
        }
        
        List<StockAlert> alerts = ids.stream().map(id -> {
            StockAlert alert = new StockAlert();
            alert.setId(id);
            alert.setIsEnabled(isEnabled);
            alert.setUpdateTime(new Date());
            return alert;
        }).collect(Collectors.toList());
        
        return updateBatchById(alerts);
    }

    @Override
    public boolean checkStockAlert(Long commodityId, Long specsId, Integer currentQuantity) {
        StockAlert alert = getAlertByCommodityAndSpecs(commodityId, specsId);
        if (ObjectUtil.isNull(alert) || alert.getIsEnabled() == 0) {
            return false;
        }
        
        return currentQuantity <= alert.getAlertQuantity();
    }

    @Override
    @Scheduled(cron = "0 */30 * * * ?") // 每30分钟执行一次
    @Transactional(rollbackFor = Exception.class)
    public void executeStockAlertCheck() {
        log.info("开始执行库存预警检查...");
        
        try {
            // 查询所有启用的预警设置
            List<StockAlert> enabledAlerts = stockAlertMapper.selectEnabledAlerts();
            if (CollectionUtil.isEmpty(enabledAlerts)) {
                log.info("没有启用的预警设置");
                return;
            }
            
            int alertCount = 0;
            for (StockAlert alert : enabledAlerts) {
                // 查询当前库存
                List<Stock> stocks = stockService.selectGoodsStock(alert.getCommodityId(), alert.getSpecsId());
                int totalQuantity = stocks.stream().mapToInt(Stock::getNumber).sum();
                
                // 检查是否需要预警
                if (totalQuantity <= alert.getAlertQuantity()) {
                    // 检查是否已有未处理的预警记录
                    StockAlertRecord latestRecord = stockAlertRecordService.getLatestAlertRecord(
                        alert.getCommodityId(), alert.getSpecsId());
                    
                    if (ObjectUtil.isNull(latestRecord) || latestRecord.getAlertStatus() != 0) {
                        // 创建新的预警记录
                        stockAlertRecordService.createAlertRecord(
                            alert.getId(),
                            alert.getCommodityId(),
                            alert.getSpecsId(),
                            totalQuantity,
                            alert.getAlertQuantity(),
                            alert.getAlertLevel()
                        );
                        alertCount++;
                        log.warn("商品[{}]库存预警：当前库存[{}]，预警阈值[{}]", 
                               alert.getCommodityName(), totalQuantity, alert.getAlertQuantity());
                    }
                }
            }
            
            log.info("库存预警检查完成，共生成{}条预警记录", alertCount);
            
        } catch (Exception e) {
            log.error("执行库存预警检查时发生错误", e);
        }
    }
}